package com.demo.ocr.filtering;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.FileInputStream;
import java.io.IOException;

import static com.demo.ocr.filtering.ImageUtil.writeImg;

/**
 * @author: 李德才
 * @description:
 * @create: 2021-06-06 15:55
 **/


/**
 * *** 均值滤波 ***
 *
 *  均值滤波方法是，对待处理的当前像素，选择一个模板，该模板为其邻近的若干个像素组成，用模板的均值来替代原像素的值的方法。
 *  优点：算法简单，计算速度快；
 *  缺点：降低噪声的同时使图像产生模糊，特别是景物的边缘和细节部分。
 **/



public class AvrFiltering {

    public static void main(String[] args) {
        avrFiltering("F:\\OCR\\微信截图_20210605171455.png", "F:\\OCR\\微信截图_20210605171455-2.png", "png");
    }

    /**
     * 均值滤波
     *
     * @param srcPath  图片的存储位置
     * @param destPath 图像要保存的存储位置
     * @param format   图像要保存的存储位置
     */
    public static void avrFiltering(String srcPath, String destPath, String format) {
        BufferedImage img;
        try {
            img = ImageIO.read(new FileInputStream(srcPath));
            int w = img.getWidth();
            int h = img.getHeight();
            int[] pix = new int[w * h];
            img.getRGB(0, 0, w, h, pix, 0, w);
            int[] newPix = avrFiltering(pix, w, h);
            img.setRGB(0, 0, w, h, newPix, 0, w);
            writeImg(img, format, destPath);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 均值滤波
     *
     * @param pix 像素矩阵数组
     * @param w   矩阵的宽
     * @param h   矩阵的高
     * @return 处理后的数组
     */
    public static int[] avrFiltering(int[] pix, int w, int h) {
        int[] newPix = new int[w * h];
        ColorModel cm = ColorModel.getRGBdefault();
        int r = 0;
        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                if (x != 0 && x != w - 1 && y != 0 && y != h - 1) {
                    r = (cm.getRed(pix[x - 1 + (y - 1) * w]) + cm.getRed(pix[x + (y - 1) * w]) + cm.getRed(pix[x + 1 + (y - 1) * w])
                            + cm.getRed(pix[x - 1 + (y) * w]) + cm.getRed(pix[x + (y) * w]) + cm.getRed(pix[x + 1 + (y) * w])
                            + cm.getRed(pix[x - 1 + (y + 1) * w]) + cm.getRed(pix[x + (y + 1) * w]) + cm.getRed(pix[x + 1 + (y + 1) * w])) / 9;
                    newPix[y * w + x] = 255 << 24 | r << 16 | r << 8 | r;

                } else {
                    newPix[y * w + x] = pix[y * w + x];
                }
            }
        }
        return newPix;
    }
}
